package com.kfm.springboot.service.impl;

import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.kfm.springboot.domain.SysMenu;
import com.kfm.springboot.domain.SysRole;
import com.kfm.springboot.domain.TreeMenu;
import com.kfm.springboot.service.IndexService;
import com.kfm.springboot.service.SysMenuService;
import com.kfm.springboot.service.SysRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class IndexServiceImpl implements IndexService {

    @Autowired
    private SysRoleService roleService;

    @Autowired
    private SysMenuService menuService;

    @Override
    public Collection<TreeMenu> getMenuByUser(String id) {
        // 根据用户 id 查 角色信息
        List<SysRole> roleList = roleService.findRoleByUser(id);

        Set<SysMenu> menus = new HashSet<>();
        // 根据角色信息 查 菜单
        for (SysRole sysRole : roleList){
            List<SysMenu> menuList = menuService.findMenuByRole(sysRole.getId());

            menus.addAll(menuList);
        }
        /*
            学生管理
                children: 学生列表  添加学生
            用户管理
                children: 用户列表  添加用户
         */

        List<SysMenu> collect = menus.stream().sorted((o1, o2) -> o1.getSort() - o2.getSort()).collect(Collectors.toList());

        return tree(collect, 0);
    }

    @Override
    public List<Tree<Integer>> getMenuByUser2(String id) {
        // 根据用户 id 查 角色信息
        List<SysRole> roleList = roleService.findRoleByUser(id);

        Set<SysMenu> menus = new HashSet<>();
        // 根据角色信息 查 菜单
        for (SysRole sysRole : roleList){
            List<SysMenu> menuList = menuService.findMenuByRole(sysRole.getId());

            menus.addAll(menuList);
        }
        /*
            学生管理
                children: 学生列表  添加学生
            用户管理
                children: 用户列表  添加用户
         */

        List<SysMenu> collect = menus.stream().sorted((o1, o2) -> o1.getSort() - o2.getSort()).collect(Collectors.toList());

        return treeMenus(collect);
    }


    /**
     * 构建树形菜单
     * @param list
     * @param pid
     * @return
     */
    private List<TreeMenu> tree(List<SysMenu> list, Integer pid){
        List<TreeMenu> treeMenus = new ArrayList<>();
        JsonMapper jsonMapper = new JsonMapper();
        Iterator<SysMenu> iterator = list.iterator();
        while (iterator.hasNext()){
            SysMenu current = iterator.next();
            if (current.getParentMenu().equals(pid)){
                String string = null;
                try {
                    // 将 父id 符合要求的对象存在 list 集合中
                    string = jsonMapper.writeValueAsString(current);
                    TreeMenu treeMenu = jsonMapper.readValue(string, TreeMenu.class);
                    // 去 找 当前 menu 的子菜单
                    treeMenu.setChildren(tree(list.stream().collect(Collectors.toList()), treeMenu.getId()));;

                    iterator.remove();

                    treeMenus.add(treeMenu);
                } catch (JsonProcessingException e) {
                    e.printStackTrace();
                }
            }
        }
        return treeMenus;
    }

    private List<Tree<Integer>> treeMenus(List<SysMenu> list){
        //配置
        TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
        // 自定义属性名 都要默认值的
        treeNodeConfig.setWeightKey("sort");
        treeNodeConfig.setIdKey("id");
        treeNodeConfig.setParentIdKey("parentMenu");
        treeNodeConfig.setNameKey("menuName");
        // 最大递归深度
        treeNodeConfig.setDeep(2);

        List<Tree<Integer>> build = TreeUtil.build(list, 0, treeNodeConfig, (sysMenu, tree) -> {
            tree.setId(sysMenu.getId());
            tree.setParentId(sysMenu.getParentMenu());
            tree.setWeight(sysMenu.getSort());
            tree.setName(sysMenu.getMenuName());
            // 扩展属性 ...
            tree.putExtra("path", sysMenu.getPath());
            tree.putExtra("status", sysMenu.getStatus());
        });

        return build;
    }
}
